﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
//老版本
//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	} 
//	else
//	{
//	return (double)a / (double)b;
//	}
//} 
//void Func()
//	{
//		// 这⾥可以看到如果发⽣除0错误抛出异常，另外下⾯的array和array2没有得到释放。
//		// 所以这⾥捕获异常后并不处理异常，异常还是交给外⾯处理，这⾥捕获了再重新抛出去。
//		// 但是如果array2new的时候抛异常呢，就还需要套⼀层捕获释放逻辑，这⾥更好解决⽅案
//		// 是智能指针，否则代码太戳了
//		int* array1 = new int[10];
//		int* array2 = new int[10]; // 抛异常呢
//		try
//		{
//			int len, time;
//			cin >> len >> time;
//			cout << Divide(len, time) << endl;
//		} 
//		catch(...)
//		{
//			cout << "delete []" << array1 << endl;
//			cout << "delete []" << array2 << endl;
//			delete[] array1;
//			delete[] array2;
//			throw; // 异常重新抛出，捕获到什么抛出什么
//		} 
//		// ...
//		cout << "delete []" << array1 << endl;
//		delete[] array1;
//		cout << "delete []" << array2 << endl;
//		delete[] array2;
//}
//智能指针版本
//智能指针设计思路
template<class T>
class SmartPointer
{
public:
	SmartPointer(T* ptr = nullptr)
		: _ptr(ptr)
	{
	}
	~SmartPointer()
	{
		cout << "delete _ptr" << _ptr << endl;
		delete[] _ptr;
	}

	// 重载运算符，模拟指针的⾏为，⽅便访问资源
	T& operator*()
	{
		return *_ptr;
	} 
	T* operator->()
	{
		return _ptr;
	} 
	T& operator[](size_t i)
	{
		return _ptr[i];
	}
private:
	T* _ptr;
};
//新版本
double Divide(int a, int b)
{
	// 当b == 0时抛出异常
	if (b == 0)
	{
		throw "Divide by zero condition!";
	}
	else
	{
		return (double)a / (double)b;
	}
}
void Func()
{
	// 这⾥使⽤RAII的智能指针类管理new出来的数组以后，程序简单多了
	// 而且智能指针会自动释放资源，不需要手动delete[]
	//无论正常结束还是异常结束，都会把资源释放掉
	SmartPointer<int> sp1 = new int[10];
	SmartPointer<int> sp2 = new int[10];
	//SmartPointer<int> sp3 = sp2;//智能指针的拷贝，会报错

	for (size_t i = 0; i < 10; i++)
	{
		sp1[i] = sp2[i] = i;
	} 
	int len, time;
	cin >> len >> time;
	cout << Divide(len, time) << endl;
}
int main()
{
	try
	{
		Func();
	} 
	catch(const char* errmsg)
	{
		cout << errmsg << endl;
	}
	catch(const exception & e)
	{
		cout << e.what() << endl;
	} 
	catch(...)
	{
		cout << "未知异常" << endl;
	} 
	return 0;
}